const express = require("express");

const app = express();

const joi = require("@hapi/joi");

const cors = require("cors");
// 配置跨域访问 --设置确定的源来保证验证码的时效性
app.use(
  cors({
    origin: "http://127.0.0.1:8090",
    credentials: true,
  })
);
// app.use((req, res, next) => {
//   res.header("Access-Control-Allow-Origin", "http://127.0.0.1:8090"); // 或指定特定的域
//   res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
//   res.header(
//     "Access-Control-Allow-Headers",
//     "Origin, X-Requested-With, Content-Type, Accept"
//   );
//   res.header("Access-Control-Allow-Credentials", true);
//   next();
// });

//默认application/x-www-form-urlencoded 配置 application/x-www-form-urlencoded 格式的解析
app.use(express.urlencoded({ extended: false }));

// 对res.send()的返回值进行统一封装为中间件
app.use((req, res, next) => {
  // err 可能是错误对象也可能是描述字符 code=200为成功
  res.resp = function (err, code = 0, data = null) {
    res.send({
      code,
      message: err instanceof Error ? err.message : err,
      data,
    });
  };
  next();
});

// session存储验证码信息
const session = require("express-session");
// session认证机制依赖cookie
const cookieParser = require("cookie-parser");
app.use(cookieParser());

app.use(
  session({
    secret: "react", // 对session id 相关的cookie进行签名
    resave: false, //是指每次请求是否都重新设置session cookie
    saveUninitialized: true, // 是否保存未初始化的会话
    cookie: {
      secure: false, // 如果在生产环境使用，应设置为true
      httpOnly: true,
      sameSite: "lax",
      maxAge: 1000 * 60 * 2, // 设置 session 的有效时间，单位毫秒
    },
  })
);

// // 在路由之前配置解析token的中间件
const expressJWT = require("express-jwt");
const config = require("./config");
// 非以/api开头的路由需要解析token
app.use(
  expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/api/] })
);

// 导入注册和登录路由 -- 路由采用Restful方式
const userRouter = require("./router/user");
app.use("/api", userRouter);

// 错误处理的中间件
app.use((err, req, res, next) => {
  // joi规则验证失败导致的错误
  if (err instanceof joi.ValidationError) {
    return res.resp(err);
  }
  //   express-jwt身份验证失败的错误处理
  if (err.name === "UnauthorizedError") {
    return res.resp("身份验证失败");
  }
  // 其他未知错误
  res.resp(err);
});

app.listen(3080, () => {
  console.log(
    "server for my-react-vite-ts-system listening at http:127.0.0.1:3080"
  );
});
